using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;

namespace DA.AnimGraph.Editor {
    internal class MenuBar : NonContextPaneBase {

        private VisualElement leftContainer;
        private VisualElement middleContainer;
        private VisualElement rightContainer;

        private Dictionary<string, GenericMenuButton> menuButtons;
        private PreviewWidget previewWidget;
        private DialogWindow searchWindow;

        public MenuBar(NonContextPaneBase parent) : base(parent) {
            AGEGlobal.GetInstance().style.SS_MenuBar(this, ageEnv.ageMode);
            style.flexDirection = FlexDirection.Row;

            leftContainer = new VisualElement() {
                name = "leftContainer",
                style = {
                    flexDirection = FlexDirection.Row,
                    flexGrow = 1,
                    justifyContent = Justify.FlexStart,
                    width = Length.Percent(33.33f),
                }
            };
            middleContainer = new VisualElement() {
                name = "middleContainer",
                style = {
                    flexDirection = FlexDirection.Row,
                    flexGrow = 1,
                    justifyContent = Justify.Center,
                    width = Length.Percent(33.34f),
                }
            };
            rightContainer = new VisualElement() {
                name = "rightContainer",
                style = {
                    flexDirection = FlexDirection.Row,
                    flexGrow = 1,
                    justifyContent = Justify.FlexEnd,
                    width = Length.Percent(33.33f),
                }
            };
        }

        protected override void OnDrawUI() {
            ageEnv.OnModeChanged += OnModeChanged;
            Add(leftContainer);
            Add(middleContainer);
            Add(rightContainer);
            LeftContainer();
            MiddleContainer();
            RightContainer();
        }
        protected override void OnClearUI() {
            searchWindow?.Close();
            searchWindow = null;
            ageEnv.OnModeChanged -= OnModeChanged;
            leftContainer?.Clear();
            middleContainer?.Clear();
            rightContainer?.Clear();
            Clear();
        }

        void OnModeChanged() {
            AGEGlobal.GetInstance().style.SS_MenuBar(this, ageEnv.ageMode);
            previewWidget.OnModeChanged(ageEnv.ageMode);
        }

        void LeftContainer() {
            menuButtons = new Dictionary<string, GenericMenuButton>();

            var fileButton = new GenericMenuButton("File");
            fileButton.AddMenuItem("设置", OpenSettingPane);
            fileButton.AddMenuSeparator();
            menuButtons.Add("File", fileButton);

            if (ageEnv.ageContext != null) {
                var searchButton = new GenericMenuButton("搜索");
                searchButton.AddMenuItem("搜索by节点名", () => OnSearchButtonClick("搜索by节点名", SearchDialog.SearchByNodeName));
                searchButton.AddMenuItem("搜索by黑板用法", () => OnSearchButtonClick("搜索by黑板用法", SearchDialog.SearchByBlackboardUsing));
                menuButtons.Add("搜索", searchButton);
            }

            CollectTools(ageEnv.ageContext != null);

            foreach (var button in menuButtons.Values) {
                leftContainer.Add(button);
            }
        }

        void MiddleContainer() {
            if (ageEnv.ageContext != null) {
                AddButton(middleContainer, "Save", () => {
                    ageEnv.ageContext.Save();
                });
                AddButton(middleContainer, "Export", () => {
                    ageEnv.ageContext.ExportDry();
                });
                previewWidget = new PreviewWidget(ageEnv.ageContext);
                middleContainer.Add(previewWidget);
            }
        }

        void RightContainer() {
            AddButton(rightContainer, "preview window", () => {
                PreviewWindow.OpenWindow();
            });
        }

        Button AddButton(VisualElement parent, string label, Action action) {
            var btn = new Button() {
                text = label,
                name = $"{label}_button",
            };
            btn.clicked += action;
            parent.Add(btn);
            return btn;
        }

        void CollectTools(bool includeNonBatch) {
            var (tools, batchTools) = AGEGlobal.GetInstance().CollectTools();

            foreach (var tool in batchTools) {
                if (!menuButtons.TryGetValue(tool.Item2.menu, out GenericMenuButton button)) {
                    button = new GenericMenuButton(tool.Item2.menu);
                    menuButtons.Add(tool.Item2.menu, button);
                }
                button.AddMenuItem(tool.Item2.path, () => {
                    var obj = Activator.CreateInstance(tool.Item1) as IAGBatchTool;
                    obj.Execute();
                });
            }
            if (includeNonBatch) {
                // 分割
                foreach (var button in menuButtons.Values) {
                    button.AddMenuSeparator();
                }
                foreach (var tool in tools) {
                    if (!menuButtons.TryGetValue(tool.Item2.menu, out GenericMenuButton button)) {
                        button = new GenericMenuButton(tool.Item2.menu);
                        menuButtons.Add(tool.Item2.menu, button);
                    }
                    button.AddMenuItem(tool.Item2.path, () => {
                        var obj = Activator.CreateInstance(tool.Item1) as IAGTool;
                        obj.Execute(ageEnv.ageContext);
                    });
                }
            }

        }

        void OpenSettingPane() {
            var service = ageEnv.serviceManager.GetService<OpenInMainContainerService>();
            var settingPane = new SettingPane(ageEnv);
            service.Open(settingPane);
        }

        private void OnSearchButtonClick(string title, Func<AGEEnvironment, VisualElement> buildUIFunction) {
            searchWindow?.Close();
            searchWindow = DialogWindow.ShowWindow(title);
            searchWindow.UseTemplate_1Button("关闭", buildUIFunction(ageEnv), index => {
                searchWindow = null;
            }, false);
        }
    }

    class PreviewWidget : VisualElement {
        private readonly AGEContext context;

        private const string nullChoice = "-";
        private PopupField<string> popupField;
        private Button refreshButton;
        private Button previewButton;

        public PreviewWidget(AGEContext context) {
            this.context = context;
            context.previewManager.ReGetPlayersInScene();

            style.flexDirection = FlexDirection.Row;
            this.SetBorderWidth(1);
            this.SetBorderColor(Color.grey);

            popupField = new PopupField<string>();
            popupField.RegisterValueChangedCallback(evt => {
                if (evt.newValue == nullChoice) {
                    context.previewManager.SetPreviewTarget(null);
                } else {
                    context.previewManager.SetPreviewTarget(evt.newValue);
                }
            });
            Add(popupField);

            refreshButton = new Button(() => {
                context.previewManager.ReGetPlayersInScene();
                InitPopupField();
            });
            refreshButton.text = "refresh";
            Add(refreshButton);

            previewButton = new Button(() => {
                context.previewManager.TogglePreview();
            });
            previewButton.text = "Preview";
            Add(previewButton);

            InitPopupField();
        }
        private void InitPopupField() {
            var playerList = context.previewManager.GetPreviewPlayerList();
            int index = 0;
            var choices = new List<string>() { nullChoice };
            if (playerList != null) {
                for (int i = 0; i < playerList.Count; i++) {
                    choices.Add(playerList[i].gameObject.name);
                    if (playerList[i].gameObject.name == context.previewManager.previewTargetName) {
                        index = i + 1;
                    }
                }
            }
            popupField.choices = choices;
            popupField.index = index;
            popupField.formatListItemCallback = p => p; // 决定每个选项的文本
            popupField.formatSelectedValueCallback = p => p; // 决定显示在下拉框中的文本
        }
        public void OnModeChanged(AGEMode newMode) {
            switch (newMode) {
                case AGEMode.Preview:
                    popupField.SetEnabled(false);
                    break;
                default:
                    popupField.SetEnabled(true);
                    break;
            }

        }
    }
}
